1. Project Clover database Tue Apr 9 2024 12:11:48 CDT
  2. Package com.alibaba.fastjson.parser

File ParserConfig.java

 

Coverage histogram

../../../../img/srcFileCovDistChart10.png
0% of files have more coverage

Code metrics

278
528
43
1
1,252
1,025
249
0.47
12.28
43
5.79

Classes

Class Line # Actions
ParserConfig 62 528 0% 249 72
0.9151943391.5%
 

Contributing tests

This file is covered by 3747 tests. .

Source view

1    /*
2    * Copyright 1999-2017 Alibaba Group.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10    * Unless required by applicable law or agreed to in writing, software
11    * distributed under the License is distributed on an "AS IS" BASIS,
12    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13    * See the License for the specific language governing permissions and
14    * limitations under the License.
15    */
16    package com.alibaba.fastjson.parser;
17   
18    import java.io.*;
19    import java.lang.ref.SoftReference;
20    import java.lang.ref.WeakReference;
21    import java.lang.reflect.*;
22    import java.math.BigDecimal;
23    import java.math.BigInteger;
24    import java.net.Inet4Address;
25    import java.net.Inet6Address;
26    import java.net.InetAddress;
27    import java.net.InetSocketAddress;
28    import java.net.URI;
29    import java.net.URL;
30    import java.nio.charset.Charset;
31    import java.security.AccessControlException;
32    import java.text.SimpleDateFormat;
33    import java.util.*;
34    import java.util.concurrent.ConcurrentHashMap;
35    import java.util.concurrent.ConcurrentMap;
36    import java.util.concurrent.atomic.AtomicBoolean;
37    import java.util.concurrent.atomic.AtomicInteger;
38    import java.util.concurrent.atomic.AtomicIntegerArray;
39    import java.util.concurrent.atomic.AtomicLong;
40    import java.util.concurrent.atomic.AtomicLongArray;
41    import java.util.concurrent.atomic.AtomicReference;
42    import java.util.regex.Pattern;
43   
44    import com.alibaba.fastjson.*;
45    import com.alibaba.fastjson.annotation.JSONField;
46    import com.alibaba.fastjson.annotation.JSONType;
47    import com.alibaba.fastjson.asm.ClassReader;
48    import com.alibaba.fastjson.asm.TypeCollector;
49    import com.alibaba.fastjson.parser.deserializer.*;
50    import com.alibaba.fastjson.serializer.*;
51    import com.alibaba.fastjson.spi.Module;
52    import com.alibaba.fastjson.support.moneta.MonetaCodec;
53    import com.alibaba.fastjson.util.*;
54    import com.alibaba.fastjson.util.IdentityHashMap;
55    import com.alibaba.fastjson.util.ServiceLoader;
56   
57    import javax.xml.datatype.XMLGregorianCalendar;
58   
59    /**
60    * @author wenshao[szujobs@hotmail.com]
61    */
 
62    public class ParserConfig {
63   
64    public static final String DENY_PROPERTY = "fastjson.parser.deny";
65    public static final String AUTOTYPE_ACCEPT = "fastjson.parser.autoTypeAccept";
66    public static final String AUTOTYPE_SUPPORT_PROPERTY = "fastjson.parser.autoTypeSupport";
67   
68    public static final String[] DENYS;
69    private static final String[] AUTO_TYPE_ACCEPT_LIST;
70    public static final boolean AUTO_SUPPORT;
71   
 
72  1 toggle static {
73    {
74  1 String property = IOUtils.getStringProperty(DENY_PROPERTY);
75  1 DENYS = splitItemsFormProperty(property);
76    }
77    {
78  1 String property = IOUtils.getStringProperty(AUTOTYPE_SUPPORT_PROPERTY);
79  1 AUTO_SUPPORT = "true".equals(property);
80    }
81    {
82  1 String property = IOUtils.getStringProperty(AUTOTYPE_ACCEPT);
83  1 String[] items = splitItemsFormProperty(property);
84  1 if (items == null) {
85  1 items = new String[0];
86    }
87  1 AUTO_TYPE_ACCEPT_LIST = items;
88    }
89    }
90   
 
91  5026784 toggle public static ParserConfig getGlobalInstance() {
92  5026784 return global;
93    }
94    public static ParserConfig global = new ParserConfig();
95   
96    private final IdentityHashMap<Type, ObjectDeserializer> deserializers = new IdentityHashMap<Type, ObjectDeserializer>();
97    private final IdentityHashMap<Type, IdentityHashMap<Type, ObjectDeserializer>> mixInDeserializers = new IdentityHashMap<Type, IdentityHashMap<Type, ObjectDeserializer>>(16);
98    private final ConcurrentMap<String,Class<?>> typeMapping = new ConcurrentHashMap<String,Class<?>>(16, 0.75f, 1);
99   
100    private boolean asmEnable = !ASMUtils.IS_ANDROID;
101   
102    public final SymbolTable symbolTable = new SymbolTable(4096);
103   
104    public PropertyNamingStrategy propertyNamingStrategy;
105   
106    protected ClassLoader defaultClassLoader;
107   
108    protected ASMDeserializerFactory asmFactory;
109   
110    private static boolean awtError = false;
111    private static boolean jdk8Error = false;
112    private static boolean jodaError = false;
113    private static boolean guavaError = false;
114   
115    private boolean autoTypeSupport = AUTO_SUPPORT;
116    private long[] denyHashCodes;
117    private long[] acceptHashCodes;
118   
119   
120    public final boolean fieldBased;
121    private boolean jacksonCompatible = false;
122   
123    public boolean compatibleWithJavaBean = TypeUtils.compatibleWithJavaBean;
124    private List<Module> modules = new ArrayList<Module>();
125   
 
126  79 toggle {
127  79 denyHashCodes = new long[]{
128    0x86fc2bf9beaf7aefL,
129    0x8eadd40cb2a94443L,
130    0x8f75f9fa0df03f80L,
131    0x8fd1960988bce8b4L,
132    0x9172a53f157930afL,
133    0x92122d710e364fb8L,
134    0x94305c26580f73c5L,
135    0x9437792831df7d3fL,
136    0xa123a62f93178b20L,
137    0xaa3daffdb10c4937L,
138    0xb7e8ed757f5d13a2L,
139    0xbcdd9dc12766f0ceL,
140    0xc2eb1e621f439309L,
141    0xc7599ebfe3e72406L,
142    0xc963695082fd728eL,
143    0xd9c9dbf6bbd27bb1L,
144    0xdf2ddff310cdb375L,
145    0xe09ae4604842582fL,
146    0xe603d6a51fad692bL,
147    0xe9184be55b1d962aL,
148    0xe9f20bad25f60807L,
149    0xeea210e8da2ec6e1L,
150    0xfc773ae20c827691L,
151    0xfd5bfc610056d720L,
152    0xffdd1a80f1ed3405L,
153    0x761619136cc13eL,
154    0x1603dc147a3e358L,
155    0x45b11bc78a3aba3L,
156    0xee6511b66fd5ef0L,
157    0x10b2bdca849d9b3eL,
158    0x144277b467723158L,
159    0x14db2e6fead04af0L,
160    0x2b3a37467a344cdfL,
161    0x313bb4abd8d4554cL,
162    0x332f0b5369a18310L,
163    0x33c64b921f523f2fL,
164    0x34a81ee78429fdf1L,
165    0x398f942e01920cf0L,
166    0x42d11a560fc9fba9L,
167    0x440e89208f445fb9L,
168    0x46c808a4b5841f57L,
169    0x4a3797b30328202cL,
170    0x4ba3e254e758d70dL,
171    0x4ef08c90ff16c675L,
172    0x4fd10ddc6d13821fL,
173    0x527db6b46ce3bcbcL,
174    0x599b5c1213a099acL,
175    0x5a5bd85c072e5efeL,
176    0x5d92e6ddde40ed84L,
177    0x616323f12c2ce25eL,
178    0x63a220e60a17c7b9L,
179    0x6749835432e0f0d2L,
180    0x746bd4a53ec195fbL,
181    0x74b50bb9260e31ffL,
182    0x767a586a5107feefL,
183    0x7aa7ee3627a19cf3L,
184    0x7bddd363ad3998c6L
185    };
186   
187  79 long[] hashCodes = new long[AUTO_TYPE_ACCEPT_LIST.length + 1];
188  79 for (int i = 0; i < AUTO_TYPE_ACCEPT_LIST.length; i++) {
189  0 hashCodes[i] = TypeUtils.fnv1a_64(AUTO_TYPE_ACCEPT_LIST[i]);
190    }
191  79 hashCodes[hashCodes.length - 1] = -6293031534589903644L;
192   
193  79 Arrays.sort(hashCodes);
194  79 acceptHashCodes = hashCodes;
195    }
196   
 
197  76 toggle public ParserConfig(){
198  76 this(false);
199    }
200   
 
201  78 toggle public ParserConfig(boolean fieldBase){
202  78 this(null, null, fieldBase);
203    }
204   
 
205  1 toggle public ParserConfig(ClassLoader parentClassLoader){
206  1 this(null, parentClassLoader, false);
207    }
208   
 
209  0 toggle public ParserConfig(ASMDeserializerFactory asmFactory){
210  0 this(asmFactory, null, false);
211    }
212   
 
213  79 toggle private ParserConfig(ASMDeserializerFactory asmFactory, ClassLoader parentClassLoader, boolean fieldBased){
214  79 this.fieldBased = fieldBased;
215  79 if (asmFactory == null && !ASMUtils.IS_ANDROID) {
216  79 try {
217  79 if (parentClassLoader == null) {
218  78 asmFactory = new ASMDeserializerFactory(new ASMClassLoader());
219    } else {
220  1 asmFactory = new ASMDeserializerFactory(parentClassLoader);
221    }
222    } catch (ExceptionInInitializerError error) {
223    // skip
224    } catch (AccessControlException error) {
225    // skip
226    } catch (NoClassDefFoundError error) {
227    // skip
228    }
229    }
230   
231  79 this.asmFactory = asmFactory;
232   
233  79 if (asmFactory == null) {
234  0 asmEnable = false;
235    }
236   
237  79 initDeserializers();
238   
239  79 addItemsToDeny(DENYS);
240  79 addItemsToAccept(AUTO_TYPE_ACCEPT_LIST);
241   
242    }
243   
 
244  80 toggle private void initDeserializers() {
245  80 deserializers.put(SimpleDateFormat.class, MiscCodec.instance);
246  80 deserializers.put(java.sql.Timestamp.class, SqlDateDeserializer.instance_timestamp);
247  80 deserializers.put(java.sql.Date.class, SqlDateDeserializer.instance);
248  80 deserializers.put(java.sql.Time.class, TimeDeserializer.instance);
249  80 deserializers.put(java.util.Date.class, DateCodec.instance);
250  80 deserializers.put(Calendar.class, CalendarCodec.instance);
251  80 deserializers.put(XMLGregorianCalendar.class, CalendarCodec.instance);
252   
253  80 deserializers.put(JSONObject.class, MapDeserializer.instance);
254  80 deserializers.put(JSONArray.class, CollectionCodec.instance);
255   
256  80 deserializers.put(Map.class, MapDeserializer.instance);
257  80 deserializers.put(HashMap.class, MapDeserializer.instance);
258  80 deserializers.put(LinkedHashMap.class, MapDeserializer.instance);
259  80 deserializers.put(TreeMap.class, MapDeserializer.instance);
260  80 deserializers.put(ConcurrentMap.class, MapDeserializer.instance);
261  80 deserializers.put(ConcurrentHashMap.class, MapDeserializer.instance);
262   
263  80 deserializers.put(Collection.class, CollectionCodec.instance);
264  80 deserializers.put(List.class, CollectionCodec.instance);
265  80 deserializers.put(ArrayList.class, CollectionCodec.instance);
266   
267  80 deserializers.put(Object.class, JavaObjectDeserializer.instance);
268  80 deserializers.put(String.class, StringCodec.instance);
269  80 deserializers.put(StringBuffer.class, StringCodec.instance);
270  80 deserializers.put(StringBuilder.class, StringCodec.instance);
271  80 deserializers.put(char.class, CharacterCodec.instance);
272  80 deserializers.put(Character.class, CharacterCodec.instance);
273  80 deserializers.put(byte.class, NumberDeserializer.instance);
274  80 deserializers.put(Byte.class, NumberDeserializer.instance);
275  80 deserializers.put(short.class, NumberDeserializer.instance);
276  80 deserializers.put(Short.class, NumberDeserializer.instance);
277  80 deserializers.put(int.class, IntegerCodec.instance);
278  80 deserializers.put(Integer.class, IntegerCodec.instance);
279  80 deserializers.put(long.class, LongCodec.instance);
280  80 deserializers.put(Long.class, LongCodec.instance);
281  80 deserializers.put(BigInteger.class, BigIntegerCodec.instance);
282  80 deserializers.put(BigDecimal.class, BigDecimalCodec.instance);
283  80 deserializers.put(float.class, FloatCodec.instance);
284  80 deserializers.put(Float.class, FloatCodec.instance);
285  80 deserializers.put(double.class, NumberDeserializer.instance);
286  80 deserializers.put(Double.class, NumberDeserializer.instance);
287  80 deserializers.put(boolean.class, BooleanCodec.instance);
288  80 deserializers.put(Boolean.class, BooleanCodec.instance);
289  80 deserializers.put(Class.class, MiscCodec.instance);
290  80 deserializers.put(char[].class, new CharArrayCodec());
291   
292  80 deserializers.put(AtomicBoolean.class, BooleanCodec.instance);
293  80 deserializers.put(AtomicInteger.class, IntegerCodec.instance);
294  80 deserializers.put(AtomicLong.class, LongCodec.instance);
295  80 deserializers.put(AtomicReference.class, ReferenceCodec.instance);
296   
297  80 deserializers.put(WeakReference.class, ReferenceCodec.instance);
298  80 deserializers.put(SoftReference.class, ReferenceCodec.instance);
299   
300  80 deserializers.put(UUID.class, MiscCodec.instance);
301  80 deserializers.put(TimeZone.class, MiscCodec.instance);
302  80 deserializers.put(Locale.class, MiscCodec.instance);
303  80 deserializers.put(Currency.class, MiscCodec.instance);
304   
305  80 deserializers.put(Inet4Address.class, MiscCodec.instance);
306  80 deserializers.put(Inet6Address.class, MiscCodec.instance);
307  80 deserializers.put(InetSocketAddress.class, MiscCodec.instance);
308  80 deserializers.put(File.class, MiscCodec.instance);
309  80 deserializers.put(URI.class, MiscCodec.instance);
310  80 deserializers.put(URL.class, MiscCodec.instance);
311  80 deserializers.put(Pattern.class, MiscCodec.instance);
312  80 deserializers.put(Charset.class, MiscCodec.instance);
313  80 deserializers.put(JSONPath.class, MiscCodec.instance);
314  80 deserializers.put(Number.class, NumberDeserializer.instance);
315  80 deserializers.put(AtomicIntegerArray.class, AtomicCodec.instance);
316  80 deserializers.put(AtomicLongArray.class, AtomicCodec.instance);
317  80 deserializers.put(StackTraceElement.class, StackTraceElementDeserializer.instance);
318   
319  80 deserializers.put(Serializable.class, JavaObjectDeserializer.instance);
320  80 deserializers.put(Cloneable.class, JavaObjectDeserializer.instance);
321  80 deserializers.put(Comparable.class, JavaObjectDeserializer.instance);
322  80 deserializers.put(Closeable.class, JavaObjectDeserializer.instance);
323   
324  80 deserializers.put(JSONPObject.class, new JSONPDeserializer());
325    }
326   
 
327  24 toggle private static String[] splitItemsFormProperty(final String property ){
328  24 if (property != null && property.length() > 0) {
329  3 return property.split(",");
330    }
331  21 return null;
332    }
333   
 
334  11 toggle public void configFromPropety(Properties properties) {
335    {
336  11 String property = properties.getProperty(DENY_PROPERTY);
337  11 String[] items = splitItemsFormProperty(property);
338  11 addItemsToDeny(items);
339    }
340    {
341  11 String property = properties.getProperty(AUTOTYPE_ACCEPT);
342  11 String[] items = splitItemsFormProperty(property);
343  11 addItemsToAccept(items);
344    }
345    {
346  11 String property = properties.getProperty(AUTOTYPE_SUPPORT_PROPERTY);
347  11 if ("true".equals(property)) {
348  0 this.autoTypeSupport = true;
349  11 } else if ("false".equals(property)) {
350  9 this.autoTypeSupport = false;
351    }
352    }
353    }
354   
 
355  90 toggle private void addItemsToDeny(final String[] items){
356  90 if (items == null){
357  88 return;
358    }
359   
360  6 for (int i = 0; i < items.length; ++i) {
361  4 String item = items[i];
362  4 this.addDeny(item);
363    }
364    }
365   
 
366  90 toggle private void addItemsToAccept(final String[] items){
367  90 if (items == null){
368  10 return;
369    }
370   
371  81 for (int i = 0; i < items.length; ++i) {
372  1 String item = items[i];
373  1 this.addAccept(item);
374    }
375    }
376   
 
377  20 toggle public boolean isAutoTypeSupport() {
378  20 return autoTypeSupport;
379    }
380   
 
381  18 toggle public void setAutoTypeSupport(boolean autoTypeSupport) {
382  18 this.autoTypeSupport = autoTypeSupport;
383    }
384   
 
385  2 toggle public boolean isAsmEnable() {
386  2 return asmEnable;
387    }
388   
 
389  23 toggle public void setAsmEnable(boolean asmEnable) {
390  23 this.asmEnable = asmEnable;
391    }
392   
393    /**
394    * @deprecated
395    */
 
396  0 toggle public IdentityHashMap<Type, ObjectDeserializer> getDerializers() {
397  0 return deserializers;
398    }
399   
 
400  1 toggle public IdentityHashMap<Type, ObjectDeserializer> getDeserializers() {
401  1 return deserializers;
402    }
403   
 
404  35059153 toggle public ObjectDeserializer getDeserializer(Type type) {
405  35059153 ObjectDeserializer deserializer = get(type);
406  35059153 if (deserializer != null) {
407  35057362 return deserializer;
408    }
409   
410  1791 if (type instanceof Class<?>) {
411  1497 return getDeserializer((Class<?>) type, type);
412    }
413   
414  294 if (type instanceof ParameterizedType) {
415  270 Type rawType = ((ParameterizedType) type).getRawType();
416  270 if (rawType instanceof Class<?>) {
417  270 return getDeserializer((Class<?>) rawType, type);
418    } else {
419  0 return getDeserializer(rawType);
420    }
421    }
422   
423  24 if (type instanceof WildcardType) {
424  5 WildcardType wildcardType = (WildcardType) type;
425  5 Type[] upperBounds = wildcardType.getUpperBounds();
426  5 if (upperBounds.length == 1) {
427  5 Type upperBoundType = upperBounds[0];
428  5 return getDeserializer(upperBoundType);
429    }
430    }
431   
432  19 return JavaObjectDeserializer.instance;
433    }
434   
 
435  12105 toggle public ObjectDeserializer getDeserializer(Class<?> clazz, Type type) {
436  12105 ObjectDeserializer deserializer = get(type);
437  12105 if (deserializer != null) {
438  10096 return deserializer;
439    }
440   
441  2009 if (type == null) {
442  0 type = clazz;
443    }
444   
445  2009 deserializer = get(type);
446  2009 if (deserializer != null) {
447  0 return deserializer;
448    }
449   
450    {
451  2009 JSONType annotation = TypeUtils.getAnnotation(clazz,JSONType.class);
452  2009 if (annotation != null) {
453  76 Class<?> mappingTo = annotation.mappingTo();
454  76 if (mappingTo != Void.class) {
455  5 return getDeserializer(mappingTo, mappingTo);
456    }
457    }
458    }
459   
460  2004 if (type instanceof WildcardType || type instanceof TypeVariable || type instanceof ParameterizedType) {
461  390 deserializer = get(clazz);
462    }
463   
464  2004 if (deserializer != null) {
465  293 return deserializer;
466    }
467   
468  1711 for (Module module : modules) {
469  3 deserializer = module.createDeserializer(this, clazz);
470  3 if (deserializer != null) {
471  2 putDeserializer(type, deserializer);
472  2 return deserializer;
473    }
474    }
475   
476  1709 String className = clazz.getName();
477  1709 className = className.replace('$', '.');
478   
479  1709 if (className.startsWith("java.awt.") //
480    && AwtCodec.support(clazz)) {
481  4 if (!awtError) {
482  4 String[] names = new String[] {
483    "java.awt.Point",
484    "java.awt.Font",
485    "java.awt.Rectangle",
486    "java.awt.Color"
487    };
488   
489  4 try {
490  4 for (String name : names) {
491  10 if (name.equals(className)) {
492  4 putDeserializer(Class.forName(name), deserializer = AwtCodec.instance);
493  4 return deserializer;
494    }
495    }
496    } catch (Throwable e) {
497    // skip
498  0 awtError = true;
499    }
500   
501  0 deserializer = AwtCodec.instance;
502    }
503    }
504   
505  1705 if (!jdk8Error) {
506  1705 try {
507  1705 if (className.startsWith("java.time.")) {
508  10 String[] names = new String[] {
509    "java.time.LocalDateTime",
510    "java.time.LocalDate",
511    "java.time.LocalTime",
512    "java.time.ZonedDateTime",
513    "java.time.OffsetDateTime",
514    "java.time.OffsetTime",
515    "java.time.ZoneOffset",
516    "java.time.ZoneRegion",
517    "java.time.ZoneId",
518    "java.time.Period",
519    "java.time.Duration",
520    "java.time.Instant"
521    };
522   
523  10 for (String name : names) {
524  63 if (name.equals(className)) {
525  10 putDeserializer(Class.forName(name), deserializer = Jdk8DateCodec.instance);
526  10 return deserializer;
527    }
528    }
529  1695 } else if (className.startsWith("java.util.Optional")) {
530  4 String[] names = new String[] {
531    "java.util.Optional",
532    "java.util.OptionalDouble",
533    "java.util.OptionalInt",
534    "java.util.OptionalLong"
535    };
536  4 for (String name : names) {
537  10 if (name.equals(className)) {
538  4 putDeserializer(Class.forName(name), deserializer = OptionalCodec.instance);
539  4 return deserializer;
540    }
541    }
542    }
543    } catch (Throwable e) {
544    // skip
545  0 jdk8Error = true;
546    }
547    }
548   
549  1691 if (!jodaError) {
550  1691 try {
551  1691 if (className.startsWith("org.joda.time.")) {
552  9 String[] names = new String[] {
553    "org.joda.time.DateTime",
554    "org.joda.time.LocalDate",
555    "org.joda.time.LocalDateTime",
556    "org.joda.time.LocalTime",
557    "org.joda.time.Instant",
558    "org.joda.time.Period",
559    "org.joda.time.Duration",
560    "org.joda.time.DateTimeZone",
561    "org.joda.time.format.DateTimeFormatter"
562    };
563   
564  9 for (String name : names) {
565  45 if (name.equals(className)) {
566  9 putDeserializer(Class.forName(name), deserializer = JodaCodec.instance);
567  9 return deserializer;
568    }
569    }
570    }
571    } catch (Throwable e) {
572    // skip
573  0 jodaError = true;
574    }
575    }
576   
577  1682 if ((!guavaError) //
578    && className.startsWith("com.google.common.collect.")) {
579  1 try {
580  1 String[] names = new String[] {
581    "com.google.common.collect.HashMultimap",
582    "com.google.common.collect.LinkedListMultimap",
583    "com.google.common.collect.LinkedHashMultimap",
584    "com.google.common.collect.ArrayListMultimap",
585    "com.google.common.collect.TreeMultimap"
586    };
587   
588  1 for (String name : names) {
589  4 if (name.equals(className)) {
590  1 putDeserializer(Class.forName(name), deserializer = GuavaCodec.instance);
591  1 return deserializer;
592    }
593    }
594    } catch (ClassNotFoundException e) {
595    // skip
596  0 guavaError = true;
597    }
598    }
599   
600  1681 if (className.equals("java.nio.ByteBuffer")) {
601  1 putDeserializer(clazz, deserializer = ByteBufferCodec.instance);
602    }
603   
604  1681 if (className.equals("java.nio.file.Path")) {
605  1 putDeserializer(clazz, deserializer = MiscCodec.instance);
606    }
607   
608  1681 if (clazz == Map.Entry.class) {
609  2 putDeserializer(clazz, deserializer = MiscCodec.instance);
610    }
611   
612  1680 if (className.equals("org.javamoney.moneta.Money")) {
613  0 putDeserializer(clazz, deserializer = MonetaCodec.instance);
614    }
615   
616  1681 final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
617  1681 try {
618  1681 for (AutowiredObjectDeserializer autowired : ServiceLoader.load(AutowiredObjectDeserializer.class,
619    classLoader)) {
620  0 for (Type forType : autowired.getAutowiredFor()) {
621  0 putDeserializer(forType, autowired);
622    }
623    }
624    } catch (Exception ex) {
625    // skip
626    }
627   
628  1681 if (deserializer == null) {
629  1676 deserializer = get(type);
630    }
631   
632  1681 if (deserializer != null) {
633  5 return deserializer;
634    }
635   
636  1676 if (clazz.isEnum()) {
637  51 if (jacksonCompatible) {
638  3 Method[] methods = clazz.getMethods();
639  3 for (Method method : methods) {
640  3 if (TypeUtils.isJacksonCreator(method)) {
641  3 deserializer = createJavaBeanDeserializer(clazz, type);
642  3 putDeserializer(type, deserializer);
643  3 return deserializer;
644    }
645    }
646    }
647   
648  48 Class<?> deserClass = null;
649  48 JSONType jsonType = TypeUtils.getAnnotation(clazz, JSONType.class);
650  48 if (jsonType != null) {
651  4 deserClass = jsonType.deserializer();
652  4 try {
653  4 deserializer = (ObjectDeserializer) deserClass.newInstance();
654  3 putDeserializer(clazz, deserializer);
655  3 return deserializer;
656    } catch (Throwable error) {
657    // skip
658    }
659    }
660   
661  45 deserializer = new EnumDeserializer(clazz);
662  1625 } else if (clazz.isArray()) {
663  72 deserializer = ObjectArrayCodec.instance;
664  1553 } else if (clazz == Set.class || clazz == HashSet.class || clazz == Collection.class || clazz == List.class
665    || clazz == ArrayList.class) {
666  14 deserializer = CollectionCodec.instance;
667  1539 } else if (Collection.class.isAssignableFrom(clazz)) {
668  24 deserializer = CollectionCodec.instance;
669  1515 } else if (Map.class.isAssignableFrom(clazz)) {
670  16 deserializer = MapDeserializer.instance;
671  1499 } else if (Throwable.class.isAssignableFrom(clazz)) {
672  13 deserializer = new ThrowableDeserializer(this, clazz);
673  1486 } else if (PropertyProcessable.class.isAssignableFrom(clazz)) {
674  1 deserializer = new PropertyProcessableDeserializer((Class<PropertyProcessable>) clazz);
675  1485 } else if (clazz == InetAddress.class) {
676  1 deserializer = MiscCodec.instance;
677    } else {
678  1484 deserializer = createJavaBeanDeserializer(clazz, type);
679    }
680   
681  1667 putDeserializer(type, deserializer);
682   
683  1667 return deserializer;
684    }
685   
686    /**
687    *
688    * @since 1.2.25
689    */
 
690  1 toggle public void initJavaBeanDeserializers(Class<?>... classes) {
691  1 if (classes == null) {
692  0 return;
693    }
694   
695  1 for (Class<?> type : classes) {
696  1 if (type == null) {
697  0 continue;
698    }
699  1 ObjectDeserializer deserializer = createJavaBeanDeserializer(type, type);
700  1 putDeserializer(type, deserializer);
701    }
702    }
703   
 
704  1488 toggle public ObjectDeserializer createJavaBeanDeserializer(Class<?> clazz, Type type) {
705  1488 boolean asmEnable = this.asmEnable & !this.fieldBased;
706  1488 if (asmEnable) {
707  1463 JSONType jsonType = TypeUtils.getAnnotation(clazz,JSONType.class);
708   
709  1463 if (jsonType != null) {
710  67 Class<?> deserializerClass = jsonType.deserializer();
711  67 if (deserializerClass != Void.class) {
712  1 try {
713  1 Object deseralizer = deserializerClass.newInstance();
714  1 if (deseralizer instanceof ObjectDeserializer) {
715  1 return (ObjectDeserializer) deseralizer;
716    }
717    } catch (Throwable e) {
718    // skip
719    }
720    }
721   
722  66 asmEnable = jsonType.asm();
723    }
724   
725  1462 if (asmEnable) {
726  1460 Class<?> superClass = JavaBeanInfo.getBuilderClass(clazz, jsonType);
727  1460 if (superClass == null) {
728  1446 superClass = clazz;
729    }
730   
731  1460 for (;;) {
732  1562 if (!Modifier.isPublic(superClass.getModifiers())) {
733  164 asmEnable = false;
734  164 break;
735    }
736   
737  1398 superClass = superClass.getSuperclass();
738  1398 if (superClass == Object.class || superClass == null) {
739  1296 break;
740    }
741    }
742    }
743    }
744   
745  1487 if (clazz.getTypeParameters().length != 0) {
746  91 asmEnable = false;
747    }
748   
749  1487 if (asmEnable && asmFactory != null && asmFactory.classLoader.isExternalClass(clazz)) {
750  22 asmEnable = false;
751    }
752   
753  1487 if (asmEnable) {
754  1189 asmEnable = ASMUtils.checkName(clazz.getSimpleName());
755    }
756   
757  1487 if (asmEnable) {
758  1188 if (clazz.isInterface()) {
759  15 asmEnable = false;
760    }
761  1188 JavaBeanInfo beanInfo = JavaBeanInfo.build(clazz
762    , type
763    , propertyNamingStrategy
764    ,false
765    , TypeUtils.compatibleWithJavaBean
766    , jacksonCompatible
767    );
768   
769  1186 if (asmEnable && beanInfo.fields.length > 200) {
770  1 asmEnable = false;
771    }
772   
773  1186 Constructor<?> defaultConstructor = beanInfo.defaultConstructor;
774  1186 if (asmEnable && defaultConstructor == null && !clazz.isInterface()) {
775  75 asmEnable = false;
776    }
777   
778  1186 for (FieldInfo fieldInfo : beanInfo.fields) {
779  2799 if (fieldInfo.getOnly) {
780  40 asmEnable = false;
781  40 break;
782    }
783   
784  2759 Class<?> fieldClass = fieldInfo.fieldClass;
785  2759 if (!Modifier.isPublic(fieldClass.getModifiers())) {
786  6 asmEnable = false;
787  6 break;
788    }
789   
790  2753 if (fieldClass.isMemberClass() && !Modifier.isStatic(fieldClass.getModifiers())) {
791  6 asmEnable = false;
792  6 break;
793    }
794   
795  2747 if (fieldInfo.getMember() != null //
796    && !ASMUtils.checkName(fieldInfo.getMember().getName())) {
797  2 asmEnable = false;
798  2 break;
799    }
800   
801  2745 JSONField annotation = fieldInfo.getAnnotation();
802  2745 if (annotation != null //
803    && ((!ASMUtils.checkName(annotation.name())) //
804    || annotation.format().length() != 0 //
805    || annotation.deserializeUsing() != Void.class //
806    || annotation.unwrapped())
807    || (fieldInfo.method != null && fieldInfo.method.getParameterTypes().length > 1)) {
808  37 asmEnable = false;
809  37 break;
810    }
811   
812  2708 if (fieldClass.isEnum()) { // EnumDeserializer
813  40 ObjectDeserializer fieldDeser = this.getDeserializer(fieldClass);
814  40 if (!(fieldDeser instanceof EnumDeserializer)) {
815  6 asmEnable = false;
816  6 break;
817    }
818    }
819    }
820    }
821   
822  1485 if (asmEnable) {
823  1001 if (clazz.isMemberClass() && !Modifier.isStatic(clazz.getModifiers())) {
824  10 asmEnable = false;
825    }
826    }
827   
828  1485 if (asmEnable) {
829  991 if (TypeUtils.isXmlField(clazz)) {
830  1 asmEnable = false;
831    }
832    }
833   
834  1485 if (!asmEnable) {
835  495 return new JavaBeanDeserializer(this, clazz, type);
836    }
837   
838  990 JavaBeanInfo beanInfo = JavaBeanInfo.build(clazz, type, propertyNamingStrategy);
839  990 try {
840  990 return asmFactory.createJavaBeanDeserializer(this, beanInfo);
841    // } catch (VerifyError e) {
842    // e.printStackTrace();
843    // return new JavaBeanDeserializer(this, clazz, type);
844    } catch (NoSuchMethodException ex) {
845  0 return new JavaBeanDeserializer(this, clazz, type);
846    } catch (JSONException asmError) {
847  6 return new JavaBeanDeserializer(this, beanInfo);
848    } catch (Exception e) {
849  0 throw new JSONException("create asm deserializer error, " + clazz.getName(), e);
850    }
851    }
852   
 
853  3400 toggle public FieldDeserializer createFieldDeserializer(ParserConfig mapping, //
854    JavaBeanInfo beanInfo, //
855    FieldInfo fieldInfo) {
856  3400 Class<?> clazz = beanInfo.clazz;
857  3400 Class<?> fieldClass = fieldInfo.fieldClass;
858   
859  3400 Class<?> deserializeUsing = null;
860  3400 JSONField annotation = fieldInfo.getAnnotation();
861  3400 if (annotation != null) {
862  158 deserializeUsing = annotation.deserializeUsing();
863  158 if (deserializeUsing == Void.class) {
864  153 deserializeUsing = null;
865    }
866    }
867   
868  3400 if (deserializeUsing == null && (fieldClass == List.class || fieldClass == ArrayList.class)) {
869  185 return new ArrayListTypeFieldDeserializer(mapping, clazz, fieldInfo);
870    }
871   
872  3215 return new DefaultFieldDeserializer(mapping, clazz, fieldInfo);
873    }
874   
 
875  1732 toggle public void putDeserializer(Type type, ObjectDeserializer deserializer) {
876  1732 Type mixin = JSON.getMixInAnnotations(type);
877  1732 if (mixin != null) {
878  5 IdentityHashMap<Type, ObjectDeserializer> mixInClasses = this.mixInDeserializers.get(type);
879  5 if (mixInClasses == null) {
880    //多线程下可能会重复创建,但不影响正确性
881  4 mixInClasses = new IdentityHashMap<Type, ObjectDeserializer>(4);
882  4 this.mixInDeserializers.put(type, mixInClasses);
883    }
884  5 mixInClasses.put(mixin, deserializer);
885    } else {
886  1727 this.deserializers.put(type, deserializer);
887    }
888    }
889   
 
890  35077362 toggle public ObjectDeserializer get(Type type) {
891  35077362 Type mixin = JSON.getMixInAnnotations(type);
892  35077362 if (null == mixin) {
893  35077342 return this.deserializers.get(type);
894    }
895  20 IdentityHashMap<Type, ObjectDeserializer> mixInClasses = this.mixInDeserializers.get(type);
896  20 if (mixInClasses == null) {
897  16 return null;
898    }
899  4 return mixInClasses.get(mixin);
900    }
901   
 
902  0 toggle public ObjectDeserializer getDeserializer(FieldInfo fieldInfo) {
903  0 return getDeserializer(fieldInfo.fieldClass, fieldInfo.fieldType);
904    }
905   
906    /**
907    * @deprecated internal method, dont call
908    */
 
909  0 toggle public boolean isPrimitive(Class<?> clazz) {
910  0 return isPrimitive2(clazz);
911    }
912   
913    /**
914    * @deprecated internal method, dont call
915    */
 
916  1004581 toggle public static boolean isPrimitive2(Class<?> clazz) {
917  1004581 return clazz.isPrimitive() //
918    || clazz == Boolean.class //
919    || clazz == Character.class //
920    || clazz == Byte.class //
921    || clazz == Short.class //
922    || clazz == Integer.class //
923    || clazz == Long.class //
924    || clazz == Float.class //
925    || clazz == Double.class //
926    || clazz == BigInteger.class //
927    || clazz == BigDecimal.class //
928    || clazz == String.class //
929    || clazz == java.util.Date.class //
930    || clazz == java.sql.Date.class //
931    || clazz == java.sql.Time.class //
932    || clazz == java.sql.Timestamp.class //
933    || clazz.isEnum() //
934    ;
935    }
936   
937    /**
938    * fieldName,field ,先生成fieldName的快照,减少之后的findField的轮询
939    *
940    * @param clazz
941    * @param fieldCacheMap :map&lt;fieldName ,Field&gt;
942    */
 
943  1599 toggle public static void parserAllFieldToCache(Class<?> clazz,Map</**fieldName*/String , Field> fieldCacheMap){
944  1599 Field[] fields = clazz.getDeclaredFields();
945  1599 for (Field field : fields) {
946  10168 String fieldName = field.getName();
947  10168 if (!fieldCacheMap.containsKey(fieldName)) {
948  10135 fieldCacheMap.put(fieldName, field);
949    }
950    }
951  1599 if (clazz.getSuperclass() != null && clazz.getSuperclass() != Object.class) {
952  122 parserAllFieldToCache(clazz.getSuperclass(), fieldCacheMap);
953    }
954    }
955   
 
956  2684 toggle public static Field getFieldFromCache(String fieldName, Map<String, Field> fieldCacheMap) {
957  2684 Field field = fieldCacheMap.get(fieldName);
958   
959  2684 if (field == null) {
960  178 field = fieldCacheMap.get("_" + fieldName);
961    }
962   
963  2684 if (field == null) {
964  175 field = fieldCacheMap.get("m_" + fieldName);
965    }
966   
967  2684 if (field == null) {
968  173 char c0 = fieldName.charAt(0);
969  173 if (c0 >= 'a' && c0 <= 'z') {
970  168 char[] chars = fieldName.toCharArray();
971  168 chars[0] -= 32; // lower
972  168 String fieldNameX = new String(chars);
973  168 field = fieldCacheMap.get(fieldNameX);
974    }
975   
976  173 if (fieldName.length() > 2) {
977  156 char c1 = fieldName.charAt(1);
978  156 if (fieldName.length() > 2
979    && c0 >= 'a' && c0 <= 'z'
980    && c1 >= 'A' && c1 <= 'Z') {
981  6 for (Map.Entry<String, Field> entry : fieldCacheMap.entrySet()) {
982  12 if (fieldName.equalsIgnoreCase(entry.getKey())) {
983  5 field = entry.getValue();
984  5 break;
985    }
986    }
987    }
988    }
989    }
990   
991  2684 return field;
992    }
993   
 
994  33 toggle public ClassLoader getDefaultClassLoader() {
995  33 return defaultClassLoader;
996    }
997   
 
998  0 toggle public void setDefaultClassLoader(ClassLoader defaultClassLoader) {
999  0 this.defaultClassLoader = defaultClassLoader;
1000    }
1001   
 
1002  9 toggle public void addDeny(String name) {
1003  9 if (name == null || name.length() == 0) {
1004  3 return;
1005    }
1006   
1007  6 long hash = TypeUtils.fnv1a_64(name);
1008  6 if (Arrays.binarySearch(this.denyHashCodes, hash) >= 0) {
1009  0 return;
1010    }
1011   
1012  6 long[] hashCodes = new long[this.denyHashCodes.length + 1];
1013  6 hashCodes[hashCodes.length - 1] = hash;
1014  6 System.arraycopy(this.denyHashCodes, 0, hashCodes, 0, this.denyHashCodes.length);
1015  6 Arrays.sort(hashCodes);
1016  6 this.denyHashCodes = hashCodes;
1017    }
1018   
 
1019  86 toggle public void addAccept(String name) {
1020  86 if (name == null || name.length() == 0) {
1021  0 return;
1022    }
1023   
1024  86 long hash = TypeUtils.fnv1a_64(name);
1025  86 if (Arrays.binarySearch(this.acceptHashCodes, hash) >= 0) {
1026  29 return;
1027    }
1028   
1029  57 long[] hashCodes = new long[this.acceptHashCodes.length + 1];
1030  57 hashCodes[hashCodes.length - 1] = hash;
1031  57 System.arraycopy(this.acceptHashCodes, 0, hashCodes, 0, this.acceptHashCodes.length);
1032  57 Arrays.sort(hashCodes);
1033  57 this.acceptHashCodes = hashCodes;
1034    }
1035   
 
1036  0 toggle public Class<?> checkAutoType(Class type) {
1037  0 if (get(type) != null) {
1038  0 return type;
1039    }
1040   
1041  0 return checkAutoType(type.getName(), null, JSON.DEFAULT_PARSER_FEATURE);
1042    }
1043   
 
1044  8 toggle public Class<?> checkAutoType(String typeName, Class<?> expectClass) {
1045  8 return checkAutoType(typeName, expectClass, JSON.DEFAULT_PARSER_FEATURE);
1046    }
1047   
 
1048  12825 toggle public Class<?> checkAutoType(String typeName, Class<?> expectClass, int features) {
1049  12825 if (typeName == null) {
1050  0 return null;
1051    }
1052   
1053  12825 if (typeName.length() >= 192 || typeName.length() < 3) {
1054  1 throw new JSONException("autoType is not support. " + typeName);
1055    }
1056   
1057  12824 final boolean expectClassFlag;
1058  12824 if (expectClass == null) {
1059  12787 expectClassFlag = false;
1060    } else {
1061  37 if (expectClass == Object.class
1062    || expectClass == Serializable.class
1063    || expectClass == Cloneable.class
1064    || expectClass == Closeable.class
1065    || expectClass == EventListener.class
1066    || expectClass == Iterable.class
1067    || expectClass == Collection.class
1068    ) {
1069  0 expectClassFlag = false;
1070    } else {
1071  37 expectClassFlag = true;
1072    }
1073    }
1074   
1075  12824 String className = typeName.replace('$', '.');
1076  12824 Class<?> clazz = null;
1077   
1078  12824 final long BASIC = 0xcbf29ce484222325L;
1079  12824 final long PRIME = 0x100000001b3L;
1080   
1081  12824 final long h1 = (BASIC ^ className.charAt(0)) * PRIME;
1082  12824 if (h1 == 0xaf64164c86024f1aL) { // [
1083  1 throw new JSONException("autoType is not support. " + typeName);
1084    }
1085   
1086  12823 if ((h1 ^ className.charAt(className.length() - 1)) * PRIME == 0x9198507b5af98f0L) {
1087  2 throw new JSONException("autoType is not support. " + typeName);
1088    }
1089   
1090  12821 final long h3 = (((((BASIC ^ className.charAt(0))
1091    * PRIME)
1092    ^ className.charAt(1))
1093    * PRIME)
1094    ^ className.charAt(2))
1095    * PRIME;
1096   
1097  12821 if (autoTypeSupport || expectClassFlag) {
1098  597 long hash = h3;
1099  8838 for (int i = 3; i < className.length(); ++i) {
1100  8251 hash ^= className.charAt(i);
1101  8251 hash *= PRIME;
1102  8251 if (Arrays.binarySearch(acceptHashCodes, hash) >= 0) {
1103  7 clazz = TypeUtils.loadClass(typeName, defaultClassLoader, true);
1104  7 if (clazz != null) {
1105  7 return clazz;
1106    }
1107    }
1108  8244 if (Arrays.binarySearch(denyHashCodes, hash) >= 0 && TypeUtils.getClassFromMapping(typeName) == null) {
1109  3 throw new JSONException("autoType is not support. " + typeName);
1110    }
1111    }
1112    }
1113   
1114  12811 if (clazz == null) {
1115  12811 clazz = TypeUtils.getClassFromMapping(typeName);
1116    }
1117   
1118  12811 if (clazz == null) {
1119  126 clazz = deserializers.findClass(typeName);
1120    }
1121   
1122  12811 if (clazz == null) {
1123  107 clazz = typeMapping.get(typeName);
1124    }
1125   
1126  12811 if (clazz != null) {
1127  12705 if (expectClass != null
1128    && clazz != java.util.HashMap.class
1129    && !expectClass.isAssignableFrom(clazz)) {
1130  0 throw new JSONException("type not match. " + typeName + " -> " + expectClass.getName());
1131    }
1132   
1133  12705 return clazz;
1134    }
1135   
1136  106 if (!autoTypeSupport) {
1137  91 long hash = h3;
1138  3637 for (int i = 3; i < className.length(); ++i) {
1139  3606 char c = className.charAt(i);
1140  3606 hash ^= c;
1141  3606 hash *= PRIME;
1142   
1143  3606 if (Arrays.binarySearch(denyHashCodes, hash) >= 0) {
1144  9 throw new JSONException("autoType is not support. " + typeName);
1145    }
1146   
1147    // white list
1148  3597 if (Arrays.binarySearch(acceptHashCodes, hash) >= 0) {
1149  51 if (clazz == null) {
1150  51 clazz = TypeUtils.loadClass(typeName, defaultClassLoader, true);
1151    }
1152   
1153  51 if (expectClass != null && expectClass.isAssignableFrom(clazz)) {
1154  0 throw new JSONException("type not match. " + typeName + " -> " + expectClass.getName());
1155    }
1156   
1157  51 return clazz;
1158    }
1159    }
1160    }
1161   
1162  46 boolean jsonType = false;
1163  46 InputStream is = null;
1164  46 try {
1165  46 String resource = typeName.replace('.', '/') + ".class";
1166  46 if (defaultClassLoader != null) {
1167  0 is = defaultClassLoader.getResourceAsStream(resource);
1168    } else {
1169  46 is = ParserConfig.class.getClassLoader().getResourceAsStream(resource);
1170    }
1171  46 if (is != null) {
1172  39 ClassReader classReader = new ClassReader(is, true);
1173  39 TypeCollector visitor = new TypeCollector("<clinit>", new Class[0]);
1174  39 classReader.accept(visitor);
1175  39 jsonType = visitor.hasJsonType();
1176    }
1177    } catch (Exception e) {
1178    // skip
1179    } finally {
1180  46 IOUtils.close(is);
1181    }
1182   
1183  46 final int mask = Feature.SupportAutoType.mask;
1184  46 boolean autoTypeSupport = this.autoTypeSupport
1185    || (features & mask) != 0
1186    || (JSON.DEFAULT_PARSER_FEATURE & mask) != 0;
1187   
1188  46 if (clazz == null && (autoTypeSupport || jsonType || expectClassFlag)) {
1189  39 boolean cacheClass = autoTypeSupport || jsonType;
1190  39 clazz = TypeUtils.loadClass(typeName, defaultClassLoader, cacheClass);
1191    }
1192   
1193  46 if (clazz != null) {
1194  33 if (jsonType) {
1195  6 TypeUtils.addMapping(typeName, clazz);
1196  6 return clazz;
1197    }
1198   
1199  27 if (ClassLoader.class.isAssignableFrom(clazz) // classloader is danger
1200    || javax.sql.DataSource.class.isAssignableFrom(clazz) // dataSource can load jdbc driver
1201    || javax.sql.RowSet.class.isAssignableFrom(clazz) //
1202    ) {
1203  0 throw new JSONException("autoType is not support. " + typeName);
1204    }
1205   
1206  27 if (expectClass != null) {
1207  16 if (expectClass.isAssignableFrom(clazz)) {
1208  12 TypeUtils.addMapping(typeName, clazz);
1209  12 return clazz;
1210    } else {
1211  4 throw new JSONException("type not match. " + typeName + " -> " + expectClass.getName());
1212    }
1213    }
1214   
1215  11 JavaBeanInfo beanInfo = JavaBeanInfo.build(clazz, clazz, propertyNamingStrategy);
1216  11 if (beanInfo.creatorConstructor != null && autoTypeSupport) {
1217  0 throw new JSONException("autoType is not support. " + typeName);
1218    }
1219    }
1220   
1221  24 if (!autoTypeSupport) {
1222  7 throw new JSONException("autoType is not support. " + typeName);
1223    }
1224   
1225  17 if (clazz != null) {
1226  11 TypeUtils.addMapping(typeName, clazz);
1227    }
1228   
1229  17 return clazz;
1230    }
1231   
 
1232  1 toggle public void clearDeserializers() {
1233  1 this.deserializers.clear();
1234  1 this.initDeserializers();
1235    }
1236   
 
1237  508 toggle public boolean isJacksonCompatible() {
1238  508 return jacksonCompatible;
1239    }
1240   
 
1241  2 toggle public void setJacksonCompatible(boolean jacksonCompatible) {
1242  2 this.jacksonCompatible = jacksonCompatible;
1243    }
1244   
 
1245  1 toggle public void register(String typeName, Class type) {
1246  1 typeMapping.putIfAbsent(typeName, type);
1247    }
1248   
 
1249  3 toggle public void register(Module module) {
1250  3 this.modules.add(module);
1251    }
1252    }